package com.goldsign.pay.common.string;

import org.apache.commons.codec.binary.Base64;

import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by IntelliJ IDEA. User: YanL Date: 2015/6/24 Time: 15:08 To change
 * this template use File | Settings | File Templates.
 */
public class StringUtil {
    protected final static String DEFAULT_ENCODE = "UTF-8";
    private static Pattern pattern = Pattern.compile("[0-9]*");


    /** 返回指定长度的空格串 */
    public static String space(int n) {
        String s = "";
        for (int i = 0; i < n; i++) {
            s += " ";
        }
        return s;
    }
    
    /** 将指定字符串重复连接n次 */
    public static String repeat(String str,int n) {
        String result = "";
        for (int i = 0; i < n; i++) {
        	result += str;
        }
        return result;
    }

    /** 左补空格到指定长度 */
    public static String lSpace(String src, int n) {
        return lSpace(src, n, DEFAULT_ENCODE);
    }

    /** 左补空格到指定长度,根据所给的编码,如果超长,则自动截断 */
    public static String lSpace(String src, int n, String encode) {
        String ret = null;
        if (src == null) {
            src = "";
        }
        ret = src;
        int len = 0;
        try {
            len = src.getBytes(encode).length;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (len > n) {
            return src.substring(0, n);
        }
        for (int i = len; i < n; i++) {
            ret = " " + ret;
        }
        return ret;
    }

    /** 左补指定字符到长度n */
    public static String lPad(String src, int n, String c) {
        return lPad(src, n, c, DEFAULT_ENCODE);
    }

    /** 左补指定字符到长度n */
    public static String lPad(String src, int n, String c, String encode) {
        String ret = null;
        if (src == null) {
            src = "";
        }
        ret = src;
        int len = 0;
        try {
            len = src.getBytes(encode).length;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (len > n) {
            return src.substring(0, n);
        }
        for (int i = len; i < n; i++) {
            ret = c + ret;
        }
        return ret;
    }

    /** 右补空格到指定长度 */
    public static String rSpace(String src, int n) {
        return rSpace(src, n, DEFAULT_ENCODE);
    }

    /** 右补空格到指定长度 */
    public static String rSpace(String src, int n, String encode) {
        String ret = null;
        if (src == null) {
        	src = "";
        }
        ret = src;
        int len = 0;
        try {
            len = src.getBytes(encode).length;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (len > n) {
            return src.substring(0, n);
        }
        for (int i = len; i < n; i++) {
            ret = ret + " ";
        }
        return ret;
    }
    /**
     * 返回左边的n个字符
     * @param src
     * @param n
     * @return
     */
    public static String left(String src,int n){
    	if (src == null || src.length() <= n){
    		 return src;
    	}
    	return src.substring(0,n);           
    }
    /**
     * 返回右边的n个字符
     * @param src
     * @param n
     * @return
     */
    public static String right(String src,int n){
    	if (src == null || src.length() <= n){
    		 return src;
    	}
    	return src.substring(src.length() - n);           
    }
    /**
     * 使用指定字符替换字符串指定起止位置字符,字符串脱敏使用,如打印日志脱敏等
     * @param src
     * @param start 替换起始位置,注意:从0开始计
     * @param length 替换长度
     * @param fillChar 填充字符
     * @return
     */
    public static String stuff(String src,int start,int length,String fillChar){
    	if(length >= src.length()){
    		return repeat(fillChar,length);
    	}
    	if(length < 0){
    		length = 0;
    	}
    	return src.substring(0,start) + repeat(fillChar,length) + src.substring(start + length);
    }

    /**
     * 根据域类型格式化变长字符串,LV格式,如03abc
     * 
     * @param in
     * @param fieldType
     *            可为LL或LLL
     * @return
     */
    public static String formatLV(String in, String fieldType) {
        return formatLV(in, fieldType, DEFAULT_ENCODE);
    }

    /**
     * 根据域类型格式化变长字符串,LV格式,如03abc
     * 
     * @param in
     * @param fieldType
     *            可为LL或LLL
     * @return
     */
    public static String formatLV(String in, String fieldType, String encode) {
        if(StringUtil.isEmpty(fieldType) || StringUtil.isEmpty(in)){
        	return "";
        }
        int msgLen = 0;
        try {
            msgLen = in.getBytes(encode).length;
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
            return "";
        }
        return lPad(String.valueOf(msgLen), fieldType.length(), "0") + in;
    }

    /**
     * 根据域类型格式化变长字符串,TLV格式,如果为null或"",则返回""
     * 
     * @param in
     * @param fieldType
     *            可为LL或LLL
     * @return
     */
    public static String formatTLV(String in, String fieldType, String fieldId) {
        if (isEmpty(in)) {
            return "";
        }
        return fieldId + formatLV(in, fieldType);
    }

    /**
     * 将字符串数组格式化为自定义的变长串
     * 
     * @param in
     *            长度不能超过99
     * @return
     */
    public static String formatVarStr(String[] in) {
        if (in == null) {
            return "";
        }
        String fields = "";
        for (int i = 0; i < in.length; i++) {
            if (i < 9) {
                fields += formatTLV(in[i], "LL", "0" + (i + 1));
            } else {
                fields += formatTLV(in[i], "LL", "" + (i + 1));
            }
        }
        return fields;
    }
    /**解析一个TLV格式串,以T为键转为Map后返回*/
    public static Map<String,String> parseTLV(String tlvStr)throws Exception{
    	return parseTLV(tlvStr,"UTF-8");
    }
    /**解析一个TLV格式串,以T为键转为Map后返回*/
    public static Map<String,String> parseTLV(String tlvStr,String encoding) throws Exception{
    	Map<String,String> m = new HashMap<String,String>();
    	byte[] tlvBytes = null;
		tlvBytes = tlvStr.getBytes(encoding);
    	int length = tlvBytes.length;
    	String t = null;
    	int l = 0;
    	String v = null;
    	int index = 0;
    	while(index < length){
    		t = new String(tlvBytes,index,2);
    		l = Integer.parseInt(new String(tlvBytes,index + 2,2));
    		v = new String(tlvBytes,index + 4,l,encoding);
    		m.put(t, v);
    		index += (l + 4);
    	}
    	return m;
    }


    public static String isEmpty(String string, String defaultVal) {
        return string == null || string.trim().length() == 0 ? defaultVal : string;
    }

    public static boolean isEmpty(String string) {
        return string == null || string.trim().length() == 0;
    }
    
    public static boolean isNotEmpty(String string) {
        return string != null && string.trim().length() > 0;
    }

    /** 生成Xml节点串,为空则不生成 */
    public static String genXmlNode(String nodeName, String value) {
        return isEmpty(value) ? "" : ("<" + nodeName + ">" + value + "</" + nodeName + ">");
    }

    /**
     * 生成Xml节点串
     * 
     * @param nodeName
     * @param value
     * @param option
     *            0或null 省略为空的节点; 1 完整节点
     * @return
     */
    public static String genXmlNode(String nodeName, String value, String option) {
        if (option == null || "0".equals(option)) {
            return genXmlNode(nodeName, value);
        }
        return "<" + nodeName + ">" + (isEmpty(value) ? "" : value) + "</" + nodeName + ">";
    }

    /** 将小数数据转换为以小数位数开头的格式串 */
    public static String toDecimalVarStr(String decimalData, int n) {
        String str = null;
        String intPart = "", decimalPart = "";
        int decBits = 0;
        int deltaLen = 0;
        int decPos = decimalData.indexOf(".");
        if (decPos == -1) {
            intPart = decimalData;
            decBits = 0;
        } else {
            intPart = decimalData.substring(0, decPos);
            decimalPart = decimalData.substring(decPos + 1);
            decBits = decimalPart.length();
        }
        if (Integer.parseInt(intPart) == 0) {
            intPart = "";
        }
        if (n != 0) {
            deltaLen = n - (decBits + intPart.length() + 1);
            if (deltaLen > 0) {
                decimalPart += StringUtil.lPad("", deltaLen, "0");
                decBits += deltaLen;
            } else if (deltaLen < 0) {
                decimalPart = decimalPart.substring(0, decBits - Math.abs(deltaLen));
                decBits += deltaLen;
            }
        }
        str = decBits + intPart + decimalPart;
        return str;
    }

    /** 判断某字符串的编码(仅限GBK,ISO-8859-1,UTF-8,GB2312) */
    public static String getEncoding(String str) {
        try {
            String encode = "ISO-8859-1";
            if (str.equals(new String(str.getBytes(encode), encode))) {
                return encode;
            }
            encode = "UTF-8";
            if (str.equals(new String(str.getBytes(encode), encode))) {
                return encode;
            }
            encode = "GBK";
            if (str.equals(new String(str.getBytes(encode), encode))) {
                return encode;
            }
            encode = "GB2312";
            if (str.equals(new String(str.getBytes(encode), encode))) {
                return encode;
            }
        } catch (Exception exception) {
        }

        return "";
    }

    /**
     * 获得有效的字符串,即obj为空时，返回""，不为空，则作toString操作
     * 
     * @param Obj
     * @return 有效的字符串
     */
    public static String getAvailStr(Object Obj) {
        if (Obj == null) {
            return "";
        }else {
            return Obj.toString();
        }
    }
    /**
     * 获得有效的字符串,即obj为空时，返回""，不为空，则作toString及trim操作
     * @param Obj
     * @return
     */
    public static String getAvailStrWithTrim(Object Obj) {
        if (Obj == null) {
            return "";
        }else {
            return Obj.toString().trim();
        }
    }

    /**
     * 静态函数：替换用户输入字符串中的非法字符
     * 
     * @param str
     *            用户输入的字符串
     * @return 转换后的字符串
     */

    public static String transformWordTags(String str) {
        str = getAvailStr(str);
        StringBuffer buf = new StringBuffer(str.length() + 6);
        char ch = ' ';
        for (int i = 0; i < str.length(); i++) {
            ch = str.charAt(i);

            if (ch == '\r') {
                buf.append("");
            } else if (ch == '\n') {
                buf.append("<br/>");
            } else {
                buf.append(ch);
            }
        }
        return buf.toString().trim().replaceAll("\"", "\\\"");
    }

    public static String decodeSpecialChars(String content) {
        String afterDecode = content.replaceAll("\\(", "\\\\\\\\(");
        afterDecode = afterDecode.replaceAll("\\)", "\\\\\\\\)");
        return afterDecode;
    }

    /** 生成一个指定长度的随机数字串,有效数位最多12位,超出左补0 */
    public static String genRadomNumStr(int len) {
        int n = (len > 12 ? 12 : len);
        long a = (long) (Math.random() * Math.pow(10, n));
        return lPad(String.valueOf(a), len, "0");
    }
    
    /**产生指定位数的随机数,含字符和数字*/
 	public static String genRandom(int k) {
 		String passwd = "";
 		char[] charSet = new char[62];

 		int i = 0;
 		for (char j = '0'; j <= '9'; j++) {
 			charSet[i++] = j;
 		}
 		for (char j = 'a'; j <= 'z'; j++) {
 			charSet[i++] = j;
 		}
 		for (char j = 'A'; j <= 'Z'; j++) {
 			charSet[i++] = j;
 		}

 		for (int j = 0; j < k; j++) {
 			int index = (int) (Math.random() * 100) % 10;
 			passwd += charSet[index];
 		}
 		return passwd;
 	}

    /**
     * 判断字符串是否是数字
     */
    public static boolean isNumber(String number) {
//        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher matcher = pattern.matcher(number);

        if (matcher.matches()) {
            return true;
        }
        return false;
    }
    
    public static String formatObjectToString(Object obj){
    	return formatObjectToString(obj.toString());
    }
    /**格式化Java对象toString后的字符串*/
	public static String formatObjectToString(String str){
//		str = "Transation [account=Account [pay_id=8888, user_no=U00000000064, account_no=A00000000044, user_name=null, cert_id=null, cert_type=null, user_type=null, acc_prop=null, mobile_no=null, realname_status=null, currency=null, otherInfo={}], bank_account=null, opp_account=null, opp_bank_account=null, backout_flag=0, busi_date=20150926, order_amount=1000, order_amounts=1000, order_currency=CNY, settle_amount=1000, settle_amounts=1000, settle_currency=CNY, ccr=null, batch_flag=0, opp_accounts=null, bank_accounts=null, is_mix_pay=0, pay_type=0000, channel_code=BALANCE, summary=null, order_timeout=null, order_subject=null, price=null, quantity=null, body=null, show_url=null, user_memo=null, access_type=null, merchant_no=null, terminal_no=null, mer_order_no=null, sub_mer_pay_id=null, sub_mer_name=null, return_url=null, notify_url=null, exter_invoke_ip=null, extra_common_param=null, return_token=null, order_no=2015092600404264, trans_type=01, ex_msg={}, redirect_html=null, control_status=N, order_status=WAIT, clr_status=0, result_confirm_status=null, handle_result_code=null, handle_result_desc=null, handle_ex_msg={}]";
		int n = str.length();
		int left = 0;
		char c = 0;
		String padStr = "";
		CharArrayWriter caw = new CharArrayWriter();
		for(int i = 0; i < n; i++){
			c = str.charAt(i);
			switch(c){
			case '[':
				left++;
				padStr = "\n" + repeat("\t ",left);
				break;
			case ',':
				padStr = "\n" + repeat("\t",left);
				break;
			case ']':
				left--;
				break;
			default:
				padStr = "";
			}
			try {
				caw.write(c + padStr);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println(caw.toString());
		return caw.toString();
	}
	/**
	 * 将字节序列转为base64编码的字符串
	 * @param src
	 * @return
	 */
	public static String encodeBase64(byte[] src){
		return new String(Base64.encodeBase64(src));
	}
	/**
	 * 将字符串按当前系统编码转为base64编码的串
	 * @param src
	 * @return
	 */
	public static String encodeBase64(String src){
		return new String(Base64.encodeBase64(src.getBytes()));
	}
	/**
	 * 将字符串按照给定编码转为base64编码的字符串
	 * @param src
	 * @param encoding 为空则取默认
	 * @return
	 */
	public static String encodeBase64(String src, String encoding){
		String result = null;
		encoding = (encoding == null?DEFAULT_ENCODE:encoding);
		try{
			result = new String(Base64.encodeBase64(src.getBytes(encoding)));
		}catch(UnsupportedEncodingException e){
			e.printStackTrace();
			return null;
		}
		return result;
	}
	/**
	 * 按系统当前默认编码转换base64字符串
	 * @param base64Str
	 * @return
	 */
	public static String decodeBase64(String base64Str){
		return new String(Base64.decodeBase64(base64Str));
	}
	
	public static byte[] decodeBase64AsBytes(String base64Str){
		return Base64.decodeBase64(base64Str);
	}
	/**
	 * 按指定字符编码转换base64字符串
	 * @param base64Str
	 * @param encoding
	 * @return
	 */
	public static String decodeBase64(String base64Str,String encoding){
		try{
			encoding = (encoding == null?DEFAULT_ENCODE:encoding);
			return new String(Base64.decodeBase64(base64Str),encoding);
		}catch(UnsupportedEncodingException e){
			return null;
		}
		
	}
}
